package com.xbongbong.paas.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.config.constant.WorkflowConstant;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.NodeTypeEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.pojo.UserSimpleForNodePojo;
import com.xbongbong.paas.pojo.workflow.WorkflowNodeTreePojo;
import com.xbongbong.paas.pojo.workflow.settings.WorkflowGetPojo;
import com.xbongbong.paas.pojo.workflow.settings.vo.WorkflowEnableVO;
import com.xbongbong.paas.service.workflow.setting.WorkflowNodeSettings;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.domain.entity.LabelEntity;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.workflow.WorkflowValueTypeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.LabelModel;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.RoleModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskLogEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskLogItemEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskNodeEntity;
import com.xbongbong.workflow.enums.WorkflowConditionOperatorEnum;
import com.xbongbong.workflow.enums.WorkflowNodeTypeEnum;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.model.WorkflowTaskLogItemModel;
import com.xbongbong.workflow.model.WorkflowTaskLogModel;
import com.xbongbong.workflow.model.WorkflowTaskNodeModel;
import com.xbongbong.workflow.pojo.FilterCondition;
import com.xbongbong.workflow.pojo.nodes.ApprovalNode;
import com.xbongbong.workflow.pojo.nodes.CcNode;
import com.xbongbong.workflow.pojo.nodes.ConditionNode;
import com.xbongbong.workflow.pojo.nodes.ObtainMultiDataNode;
import com.xbongbong.workflow.pojo.nodes.ObtainSingleDataNode;
import com.xbongbong.workflow.pojo.nodes.SendMsgNode;
import com.xbongbong.workflow.pojo.nodes.WorkflowConditionFilters;
import com.xbongbong.workflow.pojo.nodes.WorkflowConditionPojo;
import com.xbongbong.workflow.pojo.nodes.WorkflowJointConditionPojo;
import com.xbongbong.workflow.pojo.nodes.WorkflowOptionalRangePojo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 吴峰
 * @date 2021/05/28 15:13
 */
@Component
public class WorkflowNodeHelp {

    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private UserModel userModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private RoleModel roleModel;
    @Resource
    @Lazy
    private Map<Integer, WorkflowNodeSettings> workflowNodeSettingsMap;
    @Resource
    private LabelModel labelModel;
    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private WorkflowTaskLogItemModel workflowTaskLogItemModel;
    @Resource
    private WorkflowTaskLogModel workflowTaskLogModel;
    @Resource
    private WorkflowTaskNodeModel workflowTaskNodeModel;

    /**
     * 获取信息
     * @param nodeList
     * @return
     */
    public WorkflowGetPojo getContent(List<WorkflowNodeEntity> nodeList, String corpid) throws XbbException {
        if (CollectionsUtil.isEmpty(nodeList)) {
            return new WorkflowGetPojo();
        }
        List<Integer> userFieldTypeList = FieldTypeEnum.getUserList();
        List<Integer> deptFieldTypeList = FieldTypeEnum.getDeptList();
        Set<Long> formIdList = new HashSet<>();
        Set<Long> workOrderIdList = new HashSet<>();
        Set<String> userIdList = new HashSet<>();
        Set<Long> departmentIdList = new HashSet<>();
        Set<Integer> roleIdList = new HashSet<>();
        Set<Long> labelIdList = new HashSet<>();
        Map<Long, String> workflowNodeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, String> labelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        nodeList.forEach(item->{
            workflowNodeMap.put(item.getId(), item.getName());
            if (Objects.equals(item.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                workOrderIdList.add(item.getFormId());
            } else {
                formIdList.add(item.getFormId());
            }
            List<OptionalRangeEntity> mainUser = new ArrayList<>();
            if (Objects.equals(WorkflowNodeTypeEnum.APPROVE_NODE.getType(), item.getType())) {

                ApprovalNode approvalNode = JSON.parseObject(item.getConfigData(), ApprovalNode.class);
                if (Objects.nonNull(approvalNode) && Objects.nonNull(approvalNode.getMainUserList())) {
                    mainUser = approvalNode.getMainUserList();
                }
            } else if (Objects.equals(WorkflowNodeTypeEnum.CC_NODE.getType(), item.getType())){
                CcNode ccNode = JSON.parseObject(item.getConfigData(), CcNode.class);
                if (Objects.nonNull(ccNode) && Objects.nonNull(ccNode.getCcUserList())) {
                    mainUser = ccNode.getCcUserList();
                }
            }else if (Objects.equals(WorkflowNodeTypeEnum.SEND_MESSAGE_NODE.getType(), item.getType())){
                SendMsgNode sendMsgNode = JSON.parseObject(item.getConfigData(), SendMsgNode.class);
                if (Objects.nonNull(sendMsgNode) && Objects.nonNull(sendMsgNode.getMessageRecipient())) {
                   List<WorkflowOptionalRangePojo> workflowOptionalRangeList = sendMsgNode.getMessageRecipient();
                    workflowOptionalRangeList.forEach(user->{
                        if (Objects.equals(user.getProperty(), OptionalRangeEnum.DEPT.getValue())) {
                            departmentIdList.add(Long.valueOf(user.getId()));
                        } else if (Objects.equals(user.getProperty(), OptionalRangeEnum.USER.getValue())) {
                            userIdList.add(user.getId());
                        } else  if (Objects.equals(user.getProperty(), OptionalRangeEnum.ROLE.getValue())) {
                            roleIdList.add(Integer.valueOf(user.getId()));
                        } else if (Objects.equals(user.getProperty(), OptionalRangeEnum.WORKFLOW_DYNAMIC_MANAGER.getValue())) {
                            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), user.getBusinessType())) {
                                workOrderIdList.add(user.getFormId());
                            } else {
                                formIdList.add(user.getFormId());
                            }
                        }
                    });
                }
            }else if (Objects.equals(WorkflowNodeTypeEnum.CONDITION_NODE.getType(), item.getType())){
                ConditionNode conditionNode = getConditionNode(item);
                if (Objects.nonNull(conditionNode) && Objects.nonNull(conditionNode.getConditions())) {
                    WorkflowJointConditionPojo conditionList = conditionNode.getConditions();

                    if (Objects.isNull(conditionList)) {
                        return;
                    }

                    List<WorkflowConditionFilters> filters = conditionList.getFilters();

                    if (CollectionsUtil.isNotEmpty(filters)) {
                        for (WorkflowConditionFilters filter : filters) {
                            List<WorkflowConditionPojo> filterFilter = filter.getFilter();

                            filterFilter.forEach(condition->{
                                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), condition.getBusinessType())) {
                                    workOrderIdList.add(condition.getFormId());
                                } else {
                                    formIdList.add(condition.getFormId());
                                }
                                if (Objects.equals(condition.getValueType(), WorkflowValueTypeEnum.FIXED_VALUE.getType())) {
                                    if (Objects.isNull(condition.getValue())) {
                                        return;
                                    }
                                    if (userFieldTypeList.contains(condition.getFieldType())) {
                                        userIdList.addAll(JSON.parseArray( JSON.toJSONString(condition.getValue()), String.class));
                                    } else if (deptFieldTypeList.contains(condition.getFieldType())) {
                                        departmentIdList.addAll(JSON.parseArray( JSON.toJSONString(condition.getValue()), Long.class));
                                    }else if (FieldTypeEnum.LABEL.getType().equals(condition.getFieldType())) {
                                        labelIdList.addAll(JSON.parseArray( JSON.toJSONString(condition.getValue()), Long.class));
                                    }
                                } else {
                                    if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), condition.getTargetBusinessType())) {
                                        workOrderIdList.add(condition.getTargetFormId());
                                    } else {
                                        formIdList.add(condition.getTargetFormId());
                                    }
                                }
                            });
                        }
                    }

                }
            }
            if (CollectionsUtil.isNotEmpty(mainUser)) {
                mainUser.forEach(user->{
                    if (Objects.equals(user.getProperty(), OptionalRangeEnum.USER.getValue())) {
                        userIdList.add(user.getId());
                    } else if (Objects.equals(user.getProperty(), OptionalRangeEnum.DEPT.getValue())) {
                        departmentIdList.add(Long.valueOf(user.getId()));
                    } else if (Objects.equals(user.getProperty(), OptionalRangeEnum.ROLE.getValue())) {
                        roleIdList.add(Integer.valueOf(user.getId()));
                    }
                });
            }
        });
        Map<String, UserEntity> userMap = new HashMap<>(userIdList.size());
        Map<Long, DepartmentEntity> departmentMap = new HashMap<>(departmentIdList.size());
        Map<Integer, RoleEntity> roleMap = new HashMap<>(roleIdList.size());
        if (CollectionsUtil.isNotEmpty(userIdList)) {
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put(ParameterConstant.CORPID, corpid);
            params.put(ParameterConstant.ID_IN, userIdList);
            List<UserEntity> userList = userModel.findEntitys(params);
            //List<UserEntity> userList = userModel.getUserNamesByIdIn( corpid, userIdList, 1);
            userList.forEach(item-> userMap.put(item.getUserId(), item));
        }
        if (CollectionsUtil.isNotEmpty(departmentIdList)) {
            List<DepartmentEntity> departmentList = departmentModel.getByDepIdIn(corpid, departmentIdList);
            departmentList.forEach(item-> departmentMap.put(item.getId(), item));
        }
        if (CollectionsUtil.isNotEmpty(roleIdList)) {
            List<RoleEntity> roleList = roleModel.getByRoleIdIn(corpid, roleIdList);
            roleList.forEach(item-> roleMap.put(item.getId(), item));
        }
        Map<Long, PaasFormEntity> formMap = proFormHelp.getFormMap(formIdList, corpid, DelEnum.NORMAL.getDel());

        Map<Long, WorkOrderFormEntity> workOrderFormMap = proFormHelp.getWorkOrderFormMap(workOrderIdList, corpid, DelEnum.NORMAL.getDel());

        Map<Long, PaasFormExplainEntity> formExplainMap = proFormHelp.getFormExplainMap(formIdList, corpid);

        Map<Long, Map<String, FieldAttrEntity>> formExplainFieldMap = new HashMap<>(formExplainMap.size());
        formExplainMap.forEach((key, value)->{
            formExplainFieldMap.put(key, ExplainUtil.getExplainAndDataIdMap(value.getExplains(), null));
        });
        Map<Long, WorkOrderExplainEntity> workOrderExplainMap = proFormHelp.getWorkOrderFormExplainMap(workOrderIdList, corpid);
        Map<Long, Map<String, FieldAttrEntity>> workOrderFormExplainFieldMap = new HashMap<>(workOrderExplainMap.size());
        workOrderExplainMap.forEach((key, value)->{
            workOrderFormExplainFieldMap.put(key, ExplainUtil.getExplainAndDataIdMap(value.getExplains(), null));
        });
        if (CollectionUtils.isNotEmpty(labelIdList)) {
            List<LabelEntity> labelList = labelModel.getByLabelIds(labelIdList, corpid);
            labelList.forEach(item->{
                labelMap.put(item.getId(), item.getName());
            });
        }
        WorkflowGetPojo workflowGetPojo = new WorkflowGetPojo(corpid, formMap, workOrderFormMap, formExplainFieldMap, workOrderFormExplainFieldMap, userMap, departmentMap, roleMap, workflowNodeMap, labelMap);
        return workflowGetPojo;
    }


    public WorkflowNodeEntity findLastNode(WorkflowNodeEntity nodeEntity) throws XbbException {
        // 前一个节点id
        String corpid = nodeEntity.getCorpid();
        String prevId = nodeEntity.getPrevId();
        Long workflowId = nodeEntity.getWorkflowId();

        WorkflowNodeEntity prevNode = workflowNodeModel.getByUId(workflowId, corpid, prevId);
        if (Objects.isNull(prevNode)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.NOT_FOUND_LAST_NODE);
        }
        if (Objects.equals(prevNode.getType(), NodeTypeEnum.CONDITION_PROCESS_NODE.getNodeType()) || Objects.equals(prevNode.getType(), NodeTypeEnum.CONDITION_WRAPPER_PROCESS_NODE.getNodeType())) {
            // 条件节点 条件块节点
            WorkflowNodeEntity workflowNodeEntity = workflowNodeModel.getByUId(nodeEntity.getWorkflowId(), corpid, prevNode.getPrevId());
            findLastNode(workflowNodeEntity);
        }
        return prevNode;
    }

    public List<WorkflowNodeTreePojo> getNodeList(List<WorkflowNodeEntity> nodeList, WorkflowGetPojo workflowGetPojo) throws XbbException {
        List<WorkflowNodeTreePojo> workflowNodeTreeList = new ArrayList<>();
        for (WorkflowNodeEntity item : nodeList) {

            WorkflowNodeSettings workflowNodeSettings = workflowNodeSettingsMap.get(item.getType());
            if (Objects.nonNull(workflowNodeSettings)) {
                WorkflowNodeTreePojo workflowNodeTreePojo = workflowNodeSettings.getContent(item, workflowGetPojo);
                WorkflowNodeTreePojo.setProperty(workflowNodeTreePojo, item.getWorkflowId(), item.getId(), item.getName(), item.getUid(), item.getPrevId(), item.getWrapperId(), item.getType(), item.getPriority());
                workflowNodeTreePojo.setMemo(item.getMemo());
                if (Objects.equals(item.getType(), WorkflowNodeTypeEnum.START_NODE.getType())) {
                    workflowNodeTreePojo.setSubType(item.getTriggerType());
                }
                workflowNodeTreeList.add(workflowNodeTreePojo);
            }
        }
        return workflowNodeTreeList;
    }



    /**
     *
     * @Description: 查看全流程，树结构可能和当前工作流不一致，需要手动重组
     * @param nodeList 工作流所有节点
     * @param currentTaskNode 当前流程节点
     * @param workflowGetPojo 保存的节点信息实体类
     * @return: java.util.List<com.xbongbong.workflow.pojo.WorkflowNodeTreePojo>
     * @Author: shen.yang
     * @Date: 2022/7/5  10:21
     */
    public List<WorkflowNodeTreePojo> getNodeListForViewWhole(List<WorkflowNodeEntity> nodeList, WorkflowTaskNodeEntity currentTaskNode, WorkflowGetPojo workflowGetPojo) throws XbbException {
        List<WorkflowNodeTreePojo> workflowNodeTreeList = new ArrayList<>();
        String corpid = workflowGetPojo.getCorpid();
        Map<Long, WorkflowNodeEntity> workflowNodeEntityMap = nodeList.stream().collect(Collectors.toMap(WorkflowNodeEntity::getId, v -> v));
        //当前节点
        WorkflowNodeEntity currentNode = workflowNodeEntityMap.get(currentTaskNode.getWorkflowNodeId());
        if(Objects.isNull(currentNode)){
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260036);
        }
        //找到当前流程的所有日志
        WorkflowTaskLogEntity workflowTaskLogEntity = workflowTaskLogModel.getByTaskid(currentTaskNode.getTaskId(), corpid);
        if(Objects.isNull(workflowTaskLogEntity)){
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260036);
        }
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID, corpid);
        params.put("workflowTaskLogId", workflowTaskLogEntity.getId());
        params.put(ParameterConstant.ORDER_BY_STR, "add_time");
        List<WorkflowTaskLogItemEntity> taskLogItemEntityList = workflowTaskLogItemModel.findEntitys(params);
        //查询所有审批和抄送节点的人员信息
        params.clear();
        params.put(ParameterConstant.CORPID, corpid);
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put(ParameterConstant.TASK_ID, currentTaskNode.getTaskId());
        params.put("nodeTypeIn", Arrays.asList(WorkflowNodeTypeEnum.CC_NODE.getType(), WorkflowNodeTypeEnum.APPROVE_NODE.getType()));
        List<WorkflowTaskNodeEntity> allTaskNode = workflowTaskNodeModel.findEntities(params);
        Map<Long, List<WorkflowTaskNodeEntity>> allNodeMap = allTaskNode.stream().collect(Collectors.toMap(WorkflowTaskNodeEntity::getWorkflowNodeId, Collections::singletonList, (v1, v2) -> {
            List<WorkflowTaskNodeEntity> result = new ArrayList<>();
            result.addAll(v1);
            result.addAll(v2);
            return result;
        }));
        //已经执行过的节点
        Set<Long> haveDoneNodeIdList = taskLogItemEntityList.stream().map(WorkflowTaskLogItemEntity::getWorkflowNodeId).collect(Collectors.toSet());
        //回退的要剔除，不能算在已执行节点
        removeBackNode(allTaskNode, haveDoneNodeIdList, taskLogItemEntityList);
        params.clear();
        params.put(ParameterConstant.CORPID, corpid);
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<UserEntity> userEntityList = userModel.findEntitys(params);
        Map<String,UserEntity> userMap = userEntityList.stream().collect(Collectors.toMap(UserEntity::getUserId, v -> v));
        //根据日志来拼接已经执行的节点
        for (int i = 0; i < taskLogItemEntityList.size(); i++) {
            WorkflowTaskLogItemEntity taskLogItemEntity = taskLogItemEntityList.get(i);
            WorkflowNodeEntity item = workflowNodeEntityMap.get(taskLogItemEntity.getWorkflowNodeId());
            WorkflowNodeSettings workflowNodeSettings = workflowNodeSettingsMap.get(item.getType());
            if (Objects.nonNull(workflowNodeSettings)) {
                WorkflowNodeTreePojo workflowNodeTreePojo;
                //获取节点内容，审批节点和抄送节点要特殊处理，不能直接拿模板的内容，因为模板可能会修改或者会有加签的情况
                if(Objects.equals(item.getType(), WorkflowNodeTypeEnum.APPROVE_NODE.getType()) || Objects.equals(item.getType(), WorkflowNodeTypeEnum.CC_NODE.getType())){
                    workflowNodeTreePojo = new WorkflowNodeTreePojo();
                }else{
                    workflowNodeTreePojo = workflowNodeSettings.getContent(item, workflowGetPojo);
                }
                if(i == 0){
                    //首节点
                    WorkflowNodeTreePojo.setProperty(workflowNodeTreePojo, item.getWorkflowId(), item.getId(), item.getName(), item.getUid(), Constant.ZERO_STRING, null, item.getType(), null);
                }else{
                    WorkflowNodeTreePojo.setProperty(workflowNodeTreePojo, item.getWorkflowId(), item.getId(), item.getName(), item.getUid(), workflowNodeEntityMap.get(taskLogItemEntityList.get(i-1).getWorkflowNodeId()).getUid(), null, item.getType(), null);
                }
                workflowNodeTreePojo.setMemo(item.getMemo());
                if (Objects.equals(item.getType(), WorkflowNodeTypeEnum.START_NODE.getType())) {
                    workflowNodeTreePojo.setSubType(item.getTriggerType());
                }
                appendNodeUserInformationForHaveDone(workflowNodeTreePojo, userMap, allNodeMap);
                workflowNodeTreeList.add(workflowNodeTreePojo);
            }
        }

        //找后续没有执行的子节点拼进去
        Map<String, WorkflowNodeEntity> allChildMap = nodeList.stream().filter(v -> Objects.equals(v.getDel(), DelEnum.NORMAL.getDel())).filter(v -> !Objects.equals(v.getType(), WorkflowNodeTypeEnum.CONDITION_NODE.getType())).collect(Collectors.toMap(WorkflowNodeEntity::getPrevId, v -> v));
        Set<String> blockNodeSet = nodeList.stream().filter(v -> Objects.equals(v.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())).map(WorkflowNodeEntity::getUid).collect(Collectors.toSet());
        Map<String, WorkflowNodeEntity> blockNodeMap = nodeList.stream().filter(v -> Objects.equals(v.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())).collect(Collectors.toMap(WorkflowNodeEntity::getUid, v -> v));
        //拼接后续节点，有条件块的需要特殊处理（可能会出现性能问题）
        formatNode(currentNode, allChildMap, blockNodeSet, blockNodeMap);
        List<WorkflowNodeEntity> afterNodeList = nodeList.stream()
                .filter(v -> Objects.equals(v.getDel(), DelEnum.NORMAL.getDel()))
                .filter(v -> !haveDoneNodeIdList.contains(v.getId()))
                .collect(Collectors.toList());
        Set<String> delBlockNodeSet = new HashSet<>();

        //先获取流程生成之后新添加的工作流节点
        List<WorkflowNodeEntity> newAddNode = afterNodeList.stream().filter(v -> v.getAddTime() > currentNode.getAddTime()).collect(Collectors.toList());
        //过滤出新加节点中的，父节点是已经执行的节点的（条件节点也过滤掉，不会直接出现在树中，是包裹在条件块中）
        Map<String, List<String>> newAddNodeAndPreNodeMap = newAddNode.stream()
                .filter(v -> !Objects.equals(v.getPrevId(), currentNode.getUid()))
                .filter(v -> !Objects.equals(v.getType(), WorkflowNodeTypeEnum.CONDITION_NODE.getType()))
                .collect(Collectors.toMap(WorkflowNodeEntity::getPrevId, v -> Collections.singletonList(v.getUid()), (v1,v2) -> {
                    List<String> result = new ArrayList<>();
                    result.addAll(v1);
                    result.addAll(v2);
                    return result;
                }));

        Set<String> delNewNodeSet = new HashSet<>();

        //已经执行过的节点的条件块要删除
        //已经执行过的节点的新加的子节点要删除，不然会影响树结构生成
        haveDoneNodeIdList.forEach(v -> {
            if(StringUtil.isNotEmpty(workflowNodeEntityMap.get(v).getWrapperId())){
                delBlockNodeSet.add(workflowNodeEntityMap.get(v).getWrapperId());
            }
            if(newAddNodeAndPreNodeMap.keySet().contains(workflowNodeEntityMap.get(v).getUid())){
                delNewNodeSet.addAll(newAddNodeAndPreNodeMap.get(workflowNodeEntityMap.get(v).getUid()));
            }
        });

        afterNodeList.forEach(v -> {
            if(Objects.equals(v.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType()) && !blockNodeSet.contains(v.getUid())) {
                delBlockNodeSet.add(v.getUid());
            }
        });
        afterNodeList.removeIf(v -> delBlockNodeSet.contains(v.getUid()) || delNewNodeSet.contains(v.getUid()));

        for (WorkflowNodeEntity nodeEntity : afterNodeList) {
            WorkflowNodeSettings workflowNodeSettings = workflowNodeSettingsMap.get(nodeEntity.getType());
            WorkflowNodeTreePojo workflowNodeTreePojo = workflowNodeSettings.getContent(nodeEntity, workflowGetPojo);
            WorkflowNodeTreePojo.setProperty(workflowNodeTreePojo, nodeEntity.getWorkflowId(), nodeEntity.getId(), nodeEntity.getName(), nodeEntity.getUid(), nodeEntity.getPrevId(), null, nodeEntity.getType(), null);
            appendNodeUserInformation(workflowNodeTreePojo, userMap, workflowNodeEntityMap);
            workflowNodeTreeList.add(workflowNodeTreePojo);
        }
        return workflowNodeTreeList;
    }

    /**
     *
     * @Description: 处理当前节点及后续子节点的继承关系（递归）
     * @param currentNode
     * @param allChildMap
     * @param blockNodeSet
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/7/14  14:45
    */
    private void formatNode(WorkflowNodeEntity currentNode, Map<String, WorkflowNodeEntity> allChildMap, Set<String> blockNodeSet, Map<String, WorkflowNodeEntity> blockNodeMap){
        WorkflowNodeEntity childNode = allChildMap.get(currentNode.getUid());
        if(Objects.nonNull(childNode)){
            formatNode(childNode, allChildMap, blockNodeSet, blockNodeMap);
        }else{
            Map<String, WorkflowNodeEntity> blockLastNodeMap = new HashMap<>(PaasConstant.DEFAULT_ACCURACY);
            formatWrapperNode(allChildMap, currentNode, blockNodeSet, blockNodeMap, blockLastNodeMap);
        }
    }
    private void removeBackNode(List<WorkflowTaskNodeEntity> allTaskNode, Set<Long> haveDoneNodeIdList, List<WorkflowTaskLogItemEntity> taskLogItemEntityList){
        List<Long> allBackNode = allTaskNode.stream().filter(v -> Objects.equals(v.getTaskType(), TaskTypeEnum.BACK.getType())).map(WorkflowTaskNodeEntity :: getWorkflowNodeId).collect(Collectors.toList());
        //记录节点回退次数
        Map<Long,Integer> backTimesMap = allBackNode.stream().collect(Collectors.toMap(v -> v, v -> 1, Integer::sum));
        //回退次数少一次，则说明执行了
        Map<Long, List<WorkflowTaskLogItemEntity>> taskLogMap = taskLogItemEntityList.stream().sorted(Comparator.comparing(WorkflowTaskLogItemEntity::getAddTime)).collect(Collectors.toMap(WorkflowTaskLogItemEntity::getWorkflowNodeId, Collections::singletonList, (v1, v2) -> {
            List<WorkflowTaskLogItemEntity> result = new ArrayList<>();
            result.addAll(v1);
            result.addAll(v2);
            return result;
        }));
        for (Map.Entry<Long, List<WorkflowTaskLogItemEntity>> entry : taskLogMap.entrySet()) {
            if(Objects.nonNull(backTimesMap.get(entry.getKey()))){
                Integer backTimes = backTimesMap.get(entry.getKey());
                if(backTimes == entry.getValue().size() - 1){
                    //是已执行节点  不做操作
                }else{
                    //回退了，算作未执行节点
                    haveDoneNodeIdList.removeIf(entry.getKey() :: equals);
                }
            }
        }
        List<Long> saveLogId = new ArrayList<>();
        for (Map.Entry<Long, List<WorkflowTaskLogItemEntity>> entry : taskLogMap.entrySet()) {
            if(entry.getValue().size() > 0){
                saveLogId.add(entry.getValue().get(0).getId());
            }
        }
        taskLogItemEntityList.removeIf(v -> (!saveLogId.contains(v.getId())) || (Objects.equals(v.getNodeType(), NodeTypeEnum.PROCESS_NODE.getNodeType()) && !haveDoneNodeIdList.contains(v.getWorkflowNodeId())));
    }

    /**
     *
     * @Description: 处理当前条件块节点及后续子节点的继承关系（递归）
     * @param currentNode
     * @param allChildMap
     * @param blockNodeSet
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/7/14  14:45
     */
    private void formatWrapperNode(Map<String, WorkflowNodeEntity> allChildMap, WorkflowNodeEntity currentNode, Set<String> blockNodeSet, Map<String, WorkflowNodeEntity> blockNodeMap,  Map<String, WorkflowNodeEntity> blockLastNodeMap){
        //判断是否归属于某条件块
        if(Objects.nonNull(currentNode.getWrapperId())){
            //要删除该条件块节点，防止后续生成树，走到不执行的条件分支
            blockNodeSet.removeIf(currentNode.getWrapperId() :: equals);
            //记录为条件块节点的最后一个内部节点
            blockLastNodeMap.put(currentNode.getWrapperId(), currentNode);
            //判断条件块是否有子节点，如果有，则其父节点改为当前节点
            WorkflowNodeEntity nodeEntity = allChildMap.get(currentNode.getWrapperId());
            if(Objects.nonNull(nodeEntity)){
                String preId = setAfterPreNode(blockNodeMap.get(currentNode.getWrapperId()), blockNodeSet, blockLastNodeMap);
                nodeEntity.setPrevId(preId);
            }else{
                //判断是否归属于某条件块
                formatWrapperNode(allChildMap, blockNodeMap.get(currentNode.getWrapperId()), blockNodeSet, blockNodeMap, blockLastNodeMap);
            }
        }
    }

    /**
     *
     * @Description: 查找外层条件块节点的子节点的preId
     * @param currentNode
     * @param blockNodeSet
     * @param blockLastNodeMap
     * @return: java.lang.String
     * @Author: shen.yang
     * @Date: 2022/8/2  11:18
    */
    private String setAfterPreNode(WorkflowNodeEntity currentNode, Set<String> blockNodeSet, Map<String, WorkflowNodeEntity> blockLastNodeMap){
        String uid;
        if(Objects.equals(currentNode.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())){
            if(!blockNodeSet.contains(currentNode.getUid())){
                //当前是条件快节点且是已经执行过的，则获取该条件块的最后节点
                WorkflowNodeEntity blockLastNode = blockLastNodeMap.get(currentNode.getUid());
                uid = setAfterPreNode(blockLastNode, blockNodeSet, blockLastNodeMap);
            }else{
                //是没执行过的，可以直接衔接
                uid = currentNode.getUid();
            }
        }else{
            uid = currentNode.getUid();
        }
        return uid;
    }


    /**
     *
     * @Description: 处理节点上的人员信息，审批节点和抄送节点（已执行节点）
     * @param workflowNodeTreePojo
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/7/14  14:45
    */
    private void appendNodeUserInformationForHaveDone(WorkflowNodeTreePojo workflowNodeTreePojo, Map<String, UserEntity> userMap, Map<Long, List<WorkflowTaskNodeEntity>> allNodeMap){
        Integer nodeType = workflowNodeTreePojo.getType();
        if(Objects.equals(nodeType, WorkflowNodeTypeEnum.CC_NODE.getType())){
            List<WorkflowTaskNodeEntity> workflowTaskNodeEntityList = allNodeMap.get(workflowNodeTreePojo.getWorkflowNodeId());
            if(CollectionUtils.isNotEmpty(workflowTaskNodeEntityList)){
                List<UserSimpleForNodePojo> nodeUserListForHaveDone = getNodeUserListForHaveDone(workflowTaskNodeEntityList, userMap);
                workflowNodeTreePojo.setCcUserList(nodeUserListForHaveDone);
                workflowNodeTreePojo.setAvatarList(nodeUserListForHaveDone.stream().map(UserSimpleForNodePojo :: getUserAvatar).collect(Collectors.toList()));
                String content = String.format(I18nMessageUtil.getMessage(WorkflowConstant.CC_NODE), StringUtils.join(nodeUserListForHaveDone.stream().map(UserSimpleForNodePojo :: getName).collect(Collectors.toList()), PaasConstant.COMMA));
                workflowNodeTreePojo.setContent(Collections.singleton(content));
            }
        }else if(Objects.equals(nodeType, WorkflowNodeTypeEnum.APPROVE_NODE.getType())){
            List<WorkflowTaskNodeEntity> value = allNodeMap.get(workflowNodeTreePojo.getWorkflowNodeId());
            List<WorkflowTaskNodeEntity> backNodeList = allNodeMap.values().stream().flatMap(List::stream).filter(v -> Objects.equals(v.getTaskType(), TaskTypeEnum.BACK.getType())).collect(Collectors.toList());
            Long recentBackTime = 0L;
            if(CollectionUtils.isNotEmpty(backNodeList)){
                recentBackTime = backNodeList.get(0).getUpdateTime();
            }
            if(value.size() > 1){
                //有多个，可能是回退的情况，会出现相同的人，取最新的
                Map<String, List<WorkflowTaskNodeEntity>> userIdTaskNodeMap = value.stream().collect(Collectors.toMap(WorkflowTaskNodeEntity::getUserId, Collections::singletonList, (v1, v2) -> {
                    List<WorkflowTaskNodeEntity> result = new ArrayList<>();
                    result.addAll(v1);
                    result.addAll(v2);
                    return result;
                }));
                for (Map.Entry<String, List<WorkflowTaskNodeEntity>> listEntry : userIdTaskNodeMap.entrySet()) {
                    if(listEntry.getValue().size() > 1){
                        listEntry.getValue().sort(Comparator.comparing(WorkflowTaskNodeEntity :: getAddTime).reversed());
                        WorkflowTaskNodeEntity workflowTaskNodeEntity = listEntry.getValue().get(0);
                        Long saveId;
                        if(Objects.equals(workflowTaskNodeEntity.getTaskType(), TaskTypeEnum.TRANSFER.getType())){
                            String transferUserId = workflowTaskNodeEntity.getTransferUserId();
                            saveId = value.stream().filter(v -> Objects.equals(v.getUserId(), transferUserId)).max(Comparator.comparing(WorkflowTaskNodeEntity::getAddTime)).get().getId();
                        }else{
                            saveId = listEntry.getValue().get(0).getId();
                        }
                        //如果有转交的，要删掉回退的移交的人员
                        for (WorkflowTaskNodeEntity taskNodeEntity : listEntry.getValue()) {
                            if(!Objects.equals(saveId, taskNodeEntity.getId()) && Objects.equals(taskNodeEntity.getTaskType(), TaskTypeEnum.TRANSFER.getType())){
                                String transferUserId = taskNodeEntity.getTransferUserId();
                                List<WorkflowTaskNodeEntity> workflowTaskNodeEntities = userIdTaskNodeMap.get(transferUserId);
                                if(CollectionUtils.isNotEmpty(workflowTaskNodeEntities)){
                                    workflowTaskNodeEntities.sort(Comparator.comparing(WorkflowTaskNodeEntity :: getAddTime).reversed());
                                    WorkflowTaskNodeEntity delTaskNode = workflowTaskNodeEntities.get(workflowTaskNodeEntities.size() - 1);
                                    workflowTaskNodeEntities.removeIf( delTaskNode :: equals);
                                    value.removeIf(delTaskNode :: equals);
                                }
                            }
                        }
                        Long finalRecentBackTime = recentBackTime;
                        value.removeIf(v -> v.getAddTime() < finalRecentBackTime);
                        value.removeIf(v -> Objects.equals(v.getUserId(), listEntry.getKey()) && !Objects.equals(v.getId(), saveId) && !Objects.equals(v.getAddSignature(), Constant.ONE));
                    }else{
                        for (WorkflowTaskNodeEntity workflowTaskNodeEntity : listEntry.getValue()) {
                            if(Objects.equals(workflowTaskNodeEntity.getAddSignature(), Constant.ONE)){
                                //回退的情况，之前的加签要过滤掉
                                if(workflowTaskNodeEntity.getAddTime() < recentBackTime){
                                    value.removeIf(v -> Objects.equals(workflowTaskNodeEntity.getId(), v.getId()));
                                }
                            }
                        }
                    }
                }
            }
            List<WorkflowTaskNodeEntity> workflowTaskNodeEntityList = allNodeMap.get(workflowNodeTreePojo.getWorkflowNodeId());
            List<String> nameList = new ArrayList<>();
            List<String> avatarList = new ArrayList<>();
            if(CollectionUtils.isNotEmpty(workflowTaskNodeEntityList)){
                List<WorkflowTaskNodeEntity> untreatedList = workflowTaskNodeEntityList.stream().filter(v -> !Objects.equals(v.getTaskType(), TaskTypeEnum.BACK.getType())).filter(v -> Objects.equals(v.getTaskType(), TaskTypeEnum.UNTREATED.getType()) || Objects.equals(v.getTaskType(), TaskTypeEnum.OTHER_COMMIT.getType())).collect(Collectors.toList());
                List<WorkflowTaskNodeEntity> haveApproveList = workflowTaskNodeEntityList.stream().filter(v -> !Objects.equals(v.getTaskType(), TaskTypeEnum.BACK.getType())).filter(v -> Objects.equals(v.getTaskType(), TaskTypeEnum.COMMIT.getType())).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(untreatedList)){
                    List<UserSimpleForNodePojo> nodeUserListForHaveDone = getNodeUserListForHaveDone(untreatedList, userMap);
                    workflowNodeTreePojo.setUntreatedApproveList(nodeUserListForHaveDone);
                    nameList.addAll(nodeUserListForHaveDone.stream().map(UserSimpleForNodePojo :: getName).collect(Collectors.toList()));
                    avatarList.addAll(nodeUserListForHaveDone.stream().map(UserSimpleForNodePojo :: getUserAvatar).collect(Collectors.toList()));
                }
                if(CollectionUtils.isNotEmpty(haveApproveList)){
                    List<UserSimpleForNodePojo> nodeUserListForHaveDone = getNodeUserListForHaveDone(haveApproveList, userMap);
                    workflowNodeTreePojo.setHaveApproveList(nodeUserListForHaveDone);
                    nameList.addAll(nodeUserListForHaveDone.stream().map(UserSimpleForNodePojo :: getName).collect(Collectors.toList()));
                    avatarList.addAll(nodeUserListForHaveDone.stream().map(UserSimpleForNodePojo :: getUserAvatar).collect(Collectors.toList()));
                }
            }
            String content = String.format(I18nMessageUtil.getMessage(WorkflowConstant.APPROVE_NODE), StringUtils.join(nameList, PaasConstant.COMMA));
            workflowNodeTreePojo.setContent(Collections.singleton(content));
            workflowNodeTreePojo.setAvatarList(avatarList);
        }

    }

    /**
     *
     * @Description: 处理节点上的人员信息，审批节点和抄送节点（未执行节点）
     * @param workflowNodeTreePojo
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/7/14  14:45
     */
    private void appendNodeUserInformation(WorkflowNodeTreePojo workflowNodeTreePojo, Map<String, UserEntity> userMap, Map<Long, WorkflowNodeEntity> allNodeMap){
        Integer nodeType = workflowNodeTreePojo.getType();
        if(Objects.equals(nodeType, WorkflowNodeTypeEnum.CC_NODE.getType())){
            WorkflowNodeEntity workflowNodeEntity = allNodeMap.get(workflowNodeTreePojo.getWorkflowNodeId());
            if(Objects.nonNull(workflowNodeEntity)){
                JSONArray ccUserList = JSONObject.parseObject(workflowNodeEntity.getConfigData()).getJSONArray("ccUserList");
                List<String> userList = new ArrayList<>();
                if(CollectionUtils.isNotEmpty(ccUserList)){
                    for (Object o : ccUserList) {
                        String userId = (String)JSONObject.parseObject(Objects.toString(o)).get("id");
                        userList.add(userId);
                    }
                }

                workflowNodeTreePojo.setCcUserList(getNodeUserList(userList, userMap));
            }
        }else if(Objects.equals(nodeType, WorkflowNodeTypeEnum.APPROVE_NODE.getType())){
            WorkflowNodeEntity workflowNodeEntity = allNodeMap.get(workflowNodeTreePojo.getWorkflowNodeId());
            if(Objects.nonNull(workflowNodeEntity)){
                JSONArray ccUserList = JSONObject.parseObject(workflowNodeEntity.getConfigData()).getJSONArray("mainUserList");
                List<String> userList = new ArrayList<>();
                if(CollectionUtils.isNotEmpty(ccUserList)){
                    for (Object o : ccUserList) {
                        String userId = (String)JSONObject.parseObject(Objects.toString(o)).get("id");
                        userList.add(userId);
                    }
                }
                workflowNodeTreePojo.setUntreatedApproveList(getNodeUserList(userList, userMap));
            }
        }
    }

    /**
     *
     * @Description: 审批和抄送节点，人员信息封装（已执行节点）
     * @param taskNodeEntityList
     * @param userMap
     * @return: java.util.List<com.xbongbong.paas.pojo.UserSimpPojo>
     * @Author: shen.yang
     * @Date: 2022/7/14  15:22
    */
    private List<UserSimpleForNodePojo> getNodeUserListForHaveDone(List<WorkflowTaskNodeEntity> taskNodeEntityList, Map<String, UserEntity> userMap){
        List<UserSimpleForNodePojo> userList = new ArrayList<>();
        for (WorkflowTaskNodeEntity workflowTaskNodeEntity : taskNodeEntityList) {
            UserEntity userEntity = userMap.get(workflowTaskNodeEntity.getUserId());
            if(Objects.nonNull(userEntity)){
                UserSimpleForNodePojo userSimpleForNodePojo = new UserSimpleForNodePojo(userEntity.getUserId(), userEntity.getName(), userEntity.getAvatar(), workflowTaskNodeEntity.getAddSignature());
                userList.add(userSimpleForNodePojo);
            }
        }
        return userList;
    }

    /**
     *
     * @Description: 审批和抄送节点，人员信息封装（未执行节点）
     * @param userIdList
     * @param userMap
     * @return: java.util.List<com.xbongbong.paas.pojo.UserSimpPojo>
     * @Author: shen.yang
     * @Date: 2022/7/14  15:22
     */
    private List<UserSimpleForNodePojo> getNodeUserList(List<String> userIdList,  Map<String, UserEntity> userMap){
        List<UserSimpleForNodePojo> userList = new ArrayList<>();
        for (String userId : userIdList) {
            UserEntity userEntity = userMap.get(userId);
            if(Objects.nonNull(userEntity)){
                UserSimpleForNodePojo userSimpPojo = new UserSimpleForNodePojo(userEntity.getUserId(), userEntity.getName(), userEntity.getAvatar());
                userList.add(userSimpPojo);
            }
        }
        return userList;
    }


    /**
     * 校验节点设置是否正确
     * @param corpid
     * @param workflowId
     * @param workflowNodeEntity
     * @throws XbbException
     */
    public void check(String corpid, Long workflowId, WorkflowNodeEntity workflowNodeEntity) throws XbbException {
        List<WorkflowNodeEntity> nodeList = workflowNodeModel.getWorkflowNodeList(corpid, workflowId, null);
        nodeList.add(workflowNodeEntity);
        WorkflowGetPojo workflowGetPojo = getContent(nodeList, corpid);
        Map<Long, WorkflowNodeEntity> workflowNodeMap = new HashMap<>(nodeList.size());
        nodeList.forEach(item->workflowNodeMap.put(item.getId(), item));
        WorkflowNodeSettings workflowNodeSettings = workflowNodeSettingsMap.get(workflowNodeEntity.getType());
        WorkflowEnableVO workflowEnableVO = workflowNodeSettings.check(workflowNodeEntity, workflowNodeMap, workflowGetPojo);
        if (Objects.equals(workflowEnableVO.getSuccess(), 0)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, workflowEnableVO.getMessage());
        }
    }

    /**
     * 获取更新数据节点的过滤条件
     * @param updateNodeId 更新节点id
     * @param corpid 公司id
     * @return 过滤条件
     * @throws XbbException
     */
    private List<FilterCondition> getConditions(Long updateNodeId, String corpid) throws XbbException{
        WorkflowNodeEntity updateNode = workflowNodeModel.getByKey(updateNodeId, corpid);
        if (Objects.isNull(updateNode)) {
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260036);
        }
        List<FilterCondition> conditions = new ArrayList<>();
        if (Objects.equals(updateNode.getType(), WorkflowNodeTypeEnum.MULTI_DATA_NODE.getType())) {
            ObtainMultiDataNode obtainMultiDataNode = JSON.parseObject(updateNode.getConfigData(), ObtainMultiDataNode.class);
            conditions = obtainMultiDataNode.getFilterCondition();
        } else if (Objects.equals(updateNode.getType(), WorkflowNodeTypeEnum.SINGLE_DATA_NODE.getType())) {
            ObtainSingleDataNode obtainSingleDataNode = JSON.parseObject(updateNode.getConfigData(), ObtainSingleDataNode.class);
            conditions = obtainSingleDataNode.getFilterCondition();
        }
        return conditions;
    }
    /**
     * 获取子表单字段容器
     * @param updateNodeId
     * @param corpid
     * @return key为节点id，value为子表单attr
     * @throws XbbException
     */
    public Map<Long, String> getSubForm(Long updateNodeId, String corpid) throws XbbException{
        List<FilterCondition> conditions = getConditions(updateNodeId, corpid);
        Map<Long, String> subFormMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionUtils.isNotEmpty(conditions)) {
            conditions.forEach(item->{
                if (Objects.equals(WorkflowValueTypeEnum.DYNAMIC_VALUE.getType(), item.getValueType()) && item.getValueAttr().contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                    List<String> attrList = ExplainUtil.getAttrByPoint(item.getValueAttr());
                    subFormMap.put(item.getTargetWorkflowNodeId(), attrList.get(0));
                }
                List<String> attrList = ExplainUtil.getAttrByPoint(item.getAttr());
                if (attrList.size() == 2) {
                    subFormMap.put(updateNodeId, attrList.get(0));
                }
            });
        }
        return subFormMap;
    }

    /**
     * 获取子表单字段容器
     * @param updateNodeId
     * @param corpid
     * @return key为节点id，value为子表单attr
     * @throws XbbException
     */
    public Map<Long, String> getSubForm(Long updateNodeId, String corpid, Integer valueType) throws XbbException{
        List<FilterCondition> conditions = getConditions(updateNodeId, corpid);
        Map<Long, String> subFormMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionUtils.isNotEmpty(conditions)) {
            conditions.forEach(item->{
                if (Objects.equals(WorkflowValueTypeEnum.DYNAMIC_VALUE.getType(), item.getValueType()) && item.getValueAttr().contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                    List<String> attrList = ExplainUtil.getAttrByPoint(item.getValueAttr());
                    subFormMap.put(item.getTargetWorkflowNodeId(), attrList.get(0));
                }
                if (Objects.equals(WorkflowValueTypeEnum.FORMULA.getType(), valueType)) {
                    List<String> attrList = ExplainUtil.getAttrByPoint(item.getAttr());
                    if (attrList.size() == 2) {
                        subFormMap.put(updateNodeId, attrList.get(0));
                    }
                }
            });
        }
        return subFormMap;
    }

    /**
     * 获取子表单字段
     * @param updateNodeId
     * @param corpid
     * @return
     * @throws XbbException
     */
    public String getSubFormAttr(Long updateNodeId, String corpid) throws XbbException {
        List<FilterCondition> conditions = getConditions(updateNodeId, corpid);
        if (CollectionUtils.isNotEmpty(conditions)) {
            for (FilterCondition item : conditions) {
                List<String> attrList = ExplainUtil.getAttrByPoint(item.getAttr());
                if (attrList.size() == BasicConstant.TWO) {
                    return attrList.get(0);
                }
            }
        }
        return "";
    }

    /**
     * 新老条件节点格式转换
     * @author 魏荣杰
     *
     */
    public ConditionNode getConditionNode(WorkflowNodeEntity workflowNodeEntity) {
        JSONObject jsonObject = JSON.parseObject(workflowNodeEntity.getConfigData());
        Object condition = jsonObject.get("conditions");

        ConditionNode conditionNode = new ConditionNode();
        if (condition instanceof List) {
            // 老数据格式转换成新格式
            WorkflowJointConditionPojo workflowJointConditionPojo = new WorkflowJointConditionPojo();
            workflowJointConditionPojo.setOperator(WorkflowConditionOperatorEnum.OR.getAlias());

            List<WorkflowConditionFilters> filters = new ArrayList<>();

            JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(condition));

            if (jsonArray.size() > 0) {
                List<WorkflowConditionPojo> collect = jsonArray.stream().map(v -> JSON.parseObject(JSON.toJSONString(v), WorkflowConditionPojo.class)).collect(Collectors.toList());

                WorkflowConditionFilters workflowConditionFilters = new WorkflowConditionFilters();
                workflowConditionFilters.setOperator(WorkflowConditionOperatorEnum.AND.getAlias());
                workflowConditionFilters.setFilter(collect);
                filters.add(workflowConditionFilters);
            }

            workflowJointConditionPojo.setFilters(filters);

            conditionNode.setConditions(workflowJointConditionPojo);
            conditionNode.setConditionType(jsonObject.getInteger("conditionType"));
            conditionNode.setEditedData(jsonObject.getInteger("editedData"));
            conditionNode.setType(jsonObject.getInteger("type"));
        } else {
            conditionNode = JSON.parseObject(workflowNodeEntity.getConfigData(), ConditionNode.class);
        }
        return conditionNode;
    }
}
